home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / packer / ha0999beta / src / machine.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  12KB  |  472 lines

  1. /***********************************************************************
  2.   This file is part of HA, a general purpose file archiver.
  3.   Copyright (C) 1995 Harri Hirvola
  4.  
  5.   This program is free software; you can redistribute it and/or modify
  6.   it under the terms of the GNU General Public License as published by
  7.   the Free Software Foundation; either version 2 of the License, or
  8.   (at your option) any later version.
  9.  
  10.   This program is distributed in the hope that it will be useful,
  11.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.   GNU General Public License for more details.
  14.  
  15.   You should have received a copy of the GNU General Public License
  16.   along with this program; if not, write to the Free Software
  17.   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ************************************************************************
  19.     HA *nix specific routines
  20. ***********************************************************************/
  21.  
  22. #include <stdlib.h>
  23. #include <ctype.h>
  24. #include <stdio.h>
  25. #include <sys/types.h>
  26. #include <utime.h>
  27. #include <time.h>
  28. #include "ha.h"
  29. #include "error.h"
  30. #include "archive.h"
  31.  
  32. #define HA_ISVTX     0x0200
  33. #define HA_ISGID     0x0400
  34. #define HA_ISUID     0x0800
  35. #define HA_IRUSR     0x0100
  36. #define HA_IWUSR     0x0080 
  37. #define HA_IXUSR     0x0040
  38. #define HA_IRGRP     0x0020
  39. #define HA_IWGRP     0x0010
  40. #define HA_IXGRP     0x0008
  41. #define HA_IROTH     0x0004
  42. #define HA_IWOTH     0x0002
  43. #define HA_IXOTH     0x0001
  44. #define HA_IFMT      0xf000
  45. #define HA_IFIFO     0x1000
  46. #define HA_IFCHR     0x2000
  47. #define HA_IFDIR     0x4000
  48. #define HA_IFBLK     0x6000
  49. #define HA_IFREG     0x8000
  50. #define HA_IFLNK     0xa000
  51. #define HA_IFSOCK    0xc000
  52. #define HA_ISDIR(m)  ((m&HA_IFMT)==HA_IFDIR)
  53. #define HA_ISCHR(m)  ((m&HA_IFMT)==HA_IFCHR)
  54. #define HA_ISBLK(m)  ((m&HA_IFMT)==HA_IFBLK)
  55. #define HA_ISLNK(m)  ((m&HA_IFMT)==HA_IFLNK)
  56. #define HA_ISFIFO(m) ((m&HA_IFMT)==HA_IFIFO)
  57. #define HA_ISSOCK(m) ((m&HA_IFMT)==HA_IFSOCK)
  58.  
  59. typedef struct {
  60.     unsigned mtype; 
  61.     unsigned attr;
  62.     unsigned user;
  63.     unsigned group;
  64. } Mdhd;
  65.  
  66. #define MDHDLEN      7           /* Length of Mdhd in archive */
  67.  
  68. static Mdhd mdhd;
  69. struct stat filestat;
  70.     
  71. static void sig_handler(int signo) {
  72.  
  73.     error(1,ERR_INT,signo);
  74. }
  75.  
  76. void md_init(void) {
  77.  
  78.     signal(SIGINT,sig_handler);    
  79.     signal(SIGTERM,sig_handler);    
  80.     signal(SIGPIPE,sig_handler);    
  81.     signal(SIGQUIT,sig_handler);    
  82.     umask(0);
  83. }
  84.  
  85. U32B md_systime(void) {
  86.  
  87.     return (U32B)time(NULL);
  88. }
  89.  
  90. static mode_t md_tomdattr(U16B haattr) {
  91.  
  92.     mode_t mdattr;
  93.  
  94.     mdattr=0;
  95.     if (haattr&HA_IRUSR) mdattr|=S_IRUSR;
  96.     if (haattr&HA_IWUSR) mdattr|=S_IWUSR;
  97.     if (haattr&HA_ISUID) mdattr|=S_ISUID;
  98.     if (haattr&HA_IXUSR) mdattr|=S_IXUSR;
  99.     if (haattr&HA_IRGRP) mdattr|=S_IRGRP;
  100.     if (haattr&HA_IWGRP) mdattr|=S_IWGRP;
  101.     if (haattr&HA_ISGID) mdattr|=S_ISGID;
  102.     if (haattr&HA_IXGRP) mdattr|=S_IXGRP;
  103.     if (haattr&HA_IROTH) mdattr|=S_IROTH;
  104.     if (haattr&HA_IWOTH) mdattr|=S_IWOTH;
  105. #ifdef S_ISVTX
  106.     if (haattr&HA_ISVTX) mdattr|=S_ISVTX;
  107. #endif
  108.     if (haattr&HA_IXOTH) mdattr|=S_IXOTH;
  109.     return mdattr;
  110. }
  111.  
  112. static U16B md_tohaattr(mode_t mdattr) {
  113.  
  114.     U16B haattr;
  115.     
  116.     haattr=0;
  117.     if (mdattr&S_IRUSR) haattr|=HA_IRUSR;
  118.     if (mdattr&S_IWUSR) haattr|=HA_IWUSR;
  119.     if (mdattr&S_ISUID) haattr|=HA_ISUID;
  120.     if (mdattr&S_IXUSR) haattr|=HA_IXUSR;
  121.     if (mdattr&S_IRGRP) haattr|=HA_IRGRP;
  122.     if (mdattr&S_IWGRP) haattr|=HA_IWGRP;
  123.     if (mdattr&S_ISGID) haattr|=HA_ISGID;
  124.     if (mdattr&S_IXGRP) haattr|=HA_IXGRP;
  125.     if (mdattr&S_IROTH) haattr|=HA_IROTH;
  126.     if (mdattr&S_IWOTH) haattr|=HA_IWOTH;
  127.     if (mdattr&S_IXOTH) haattr|=HA_IXOTH;
  128. #ifdef S_ISVTX
  129.     if (mdattr&S_ISVTX) haattr|=HA_ISVTX;
  130. #endif
  131.     if (S_ISDIR(mdattr)) haattr|=HA_IFDIR;
  132.     else if (S_ISCHR(mdattr)) haattr|=HA_IFCHR;
  133.     else if (S_ISBLK(mdattr)) haattr|=HA_IFBLK;
  134. #ifdef S_ISLNK
  135.     else if (S_ISLNK(mdattr)) haattr|=HA_IFLNK;
  136. #endif
  137. #ifdef S_ISFIFO
  138.     else if (S_ISFIFO(mdattr)) haattr|=HA_IFIFO;
  139. #endif
  140. #ifdef S_ISSOCK
  141.     else if (S_ISSOCK(mdattr)) haattr|=HA_IFSOCK;
  142. #endif
  143.     return haattr;
  144. }
  145.  
  146. static char *attrstring(unsigned haattr) {
  147.  
  148.     static char as[11];
  149.  
  150.     sprintf(as,"%c%c%c%c%c%c%c%c%c%c",
  151.         HA_ISFIFO(haattr)?'f':HA_ISSOCK(haattr)?'s':HA_ISLNK(haattr)?'l':
  152.         HA_ISDIR(haattr)?'d':HA_ISCHR(haattr)?'c':HA_ISBLK(haattr)?'b':'-',
  153.         (haattr&HA_IRUSR)?'r':'-',
  154.         (haattr&HA_IWUSR)?'w':'-',
  155.         (haattr&HA_ISUID)?(haattr&
  156.                    HA_IXUSR)?'s':'S':(haattr&HA_IXUSR)?'x':'-',
  157.         (haattr&HA_IRGRP)?'r':'-',
  158.         (haattr&HA_IWGRP)?'w':'-',
  159.         (haattr&HA_ISGID)?(haattr&
  160.                    HA_IXGRP)?'s':'S':(haattr&HA_IXGRP)?'x':'-',
  161.         (haattr&HA_IROTH)?'r':'-',
  162.         (haattr&HA_IWOTH)?'w':'-',
  163.         (haattr&HA_ISVTX)?(haattr&
  164.                    HA_IXOTH)?'t':'T':(haattr&HA_IXOTH)?'x':'-'
  165.         );
  166.     return as;
  167. }
  168.  
  169. void md_gethdr(int len, int mode) {
  170.     
  171.     static int longest=0;
  172.     static unsigned char *buf=NULL;
  173.     
  174.     if (len>longest) {
  175.     if (buf!=NULL) buf=realloc(buf,len);
  176.     else buf=malloc(len);
  177.     if (buf==NULL) error(1,ERR_MEM,"md_gethdr()");
  178.     longest=len;
  179.     }
  180.     read(arcfile,buf,len);
  181.     mdhd.mtype=buf[0];
  182.     if (mdhd.mtype==UNIXMDH) {
  183.     mdhd.attr=buf[1]|(buf[2]<<8);
  184.     mdhd.user=buf[3]|(buf[4]<<8);
  185.     mdhd.group=buf[5]|(buf[6]<<8);
  186.     }
  187.     else {
  188.     switch (mode) {
  189.       case M_DIR:
  190.         mdhd.attr=md_tohaattr(DEF_DIRATTR);
  191.         mdhd.attr|=HA_IFDIR;
  192.         break;
  193.       default:
  194.         mdhd.attr=md_tohaattr(DEF_FILEATTR);
  195.         break;
  196.     }
  197.     }
  198. }
  199.  
  200. void md_puthdr(void) {
  201.     
  202.     unsigned char buf[MDHDLEN];
  203.     
  204.     buf[0]=UNIXMDH;
  205.     buf[1]=mdhd.attr&0xff;
  206.     buf[2]=(mdhd.attr>>8)&0xff;
  207.     buf[3]=mdhd.user&0xff;
  208.     buf[4]=(mdhd.user>>8)&0xff;
  209.     buf[5]=mdhd.group&0xff;
  210.     buf[6]=(mdhd.group>>8)&0xff;
  211.     write(arcfile,buf,MDHDLEN);
  212. }
  213.  
  214. int md_filetype(char *path, char *name) {
  215.     
  216.     char *fullpath;
  217.     
  218.     if (!strcmp(name,".") || !strcmp(name,"..")) return T_SKIP;
  219.     fullpath=md_pconcat(0,path,name);
  220.     if (lstat(fullpath,&filestat)<0) {
  221.     error(0,ERR_STAT,fullpath);
  222.     free(fullpath);
  223.     return T_SKIP;
  224.     }
  225.     free(fullpath);
  226.     if (filestat.st_ino==arcstat.st_ino) return T_SKIP;
  227.     if (S_ISDIR(filestat.st_mode)) return T_DIR;
  228.     if (S_ISREG(filestat.st_mode)) return T_REGULAR;
  229.     return T_SPECIAL;
  230. }
  231.  
  232. int md_newfile(void) {
  233.     
  234.     mdhd.attr=md_tohaattr(filestat.st_mode);
  235.     mdhd.user=filestat.st_uid;
  236.     mdhd.group=filestat.st_gid;
  237.     return MDHDLEN;
  238. }
  239.  
  240. int md_special(char *fullname, unsigned char **sdata) {
  241.     
  242.     static unsigned char *dat=NULL;
  243.     int len;
  244.     
  245.     if (dat!=NULL) {
  246.     free(dat);
  247.     dat=NULL;
  248.     }
  249.     if (HA_ISCHR(mdhd.attr)||HA_ISBLK(mdhd.attr)) {
  250.     if ((dat=malloc(sizeof(dev_t)))==NULL) error(1,ERR_MEM,"md_special()");
  251.     *(dev_t*)dat=filestat.st_rdev;
  252.     *sdata=dat;
  253.     return sizeof(dev_t);
  254.     }
  255.     if (HA_ISLNK(mdhd.attr)) {
  256.     if ((dat=malloc(1024))==NULL) error(1,ERR_MEM,"md_special()");
  257.     if ((len=readlink(fullname,(char*)dat,1024))<0) 
  258.       error(1,ERR_RDLINK,fullname);
  259.     dat[len]=0;
  260.     *sdata=dat;
  261.     return len+1;
  262.     }
  263.     else {
  264.     *sdata=dat;
  265.     return 0;
  266.     }
  267. }
  268.  
  269. int md_mkspecial(char *ofname,unsigned sdlen,unsigned char *sdata) {
  270.     
  271.     if (mdhd.mtype!=UNIXMDH) {
  272.     error(0,ERR_HOW,ofname);
  273.     return 0;
  274.     }
  275.     if (HA_ISCHR(mdhd.attr)) {
  276.     mknod(ofname,md_tomdattr(mdhd.attr)|S_IFCHR,*(dev_t*)sdata);
  277.     if (useattr) chown(ofname,mdhd.user,mdhd.group);
  278.     return 1;
  279.     }
  280.     else if (HA_ISBLK(mdhd.attr)) {
  281.     mknod(ofname,md_tomdattr(mdhd.attr)|S_IFBLK,*(dev_t*)sdata);
  282.     if (useattr) chown(ofname,mdhd.user,mdhd.group);
  283.     return 1;
  284.     }
  285. #ifdef S_ISLNK
  286.     else if (HA_ISLNK(mdhd.attr)) {
  287.     if (symlink(ofname,(char*)sdata)<0) error(0,ERR_MKLINK,sdata,ofname);
  288.     if (useattr) {
  289.         chmod(ofname,md_tomdattr(mdhd.attr));
  290.         chown(ofname,mdhd.user,mdhd.group);
  291.     }
  292.     return 1;
  293.     }
  294. #endif
  295. #ifdef S_ISFIFO
  296.     else if (HA_ISFIFO(mdhd.attr)) {
  297.     if (mkfifo(ofname,md_tomdattr(mdhd.attr))<0) 
  298.       error(0,ERR_MKFIFO,sdata,ofname);
  299.     if (useattr) chown(ofname,mdhd.user,mdhd.group);
  300.     return 1;
  301.     }
  302. #endif
  303.     error(0,ERR_HOW,ofname);
  304.     return 0;
  305. }
  306.  
  307. void md_setfattrs(char *file) {
  308.     
  309.     if (useattr) {
  310.     chmod(file,md_tomdattr(mdhd.attr));
  311.     chown(file,mdhd.user,mdhd.group);
  312.     }
  313. }
  314.  
  315. void md_setft(char *file,U32B time) {
  316.     
  317.     struct utimbuf utb;
  318.     
  319.     utb.actime=time;
  320.     utb.modtime=time;
  321.     utime(file,&utb);
  322. }
  323.  
  324. void md_listhdr(void) {
  325.     
  326.     printf("\n attr");
  327. }
  328.  
  329. void md_listdat(void) {
  330.     
  331.     printf("\n %s",attrstring(mdhd.attr));
  332. }
  333.  
  334. char *md_timestring(unsigned long t) {
  335.     
  336.     static char ts[22];
  337.     struct tm *tim;    
  338.     
  339.     tim=localtime((long *)&t);
  340.     sprintf(ts,"%04d-%02d-%02d  %02d:%02d",tim->tm_year+1900,tim->tm_mon+1,
  341.         tim->tm_mday,tim->tm_hour,tim->tm_min);
  342.     return ts;    
  343. }
  344.  
  345. char *md_arcname(char *name_req) {
  346.     
  347.     int pos;
  348.     char *newname;
  349.  
  350.     pos=strlen(name_req);
  351.     if (pos>3 && 
  352.     tolower(name_req[pos-1])=='a' && 
  353.     tolower(name_req[pos-2])=='h' && 
  354.     name_req[pos-3]=='.') return name_req;
  355.     if ((newname=malloc(pos+4))==NULL) error(1,ERR_MEM,"md_arcname()");
  356.     strcpy(newname,name_req);
  357.     strcpy(newname+pos,".ha");
  358.     return newname;
  359. }
  360.  
  361. void md_truncfile(int fh, U32B len) {
  362.     
  363.     ftruncate(fh,len);    
  364. }
  365.  
  366. char *md_tohapath(char *mdpath) {
  367.     
  368.     int i,j;
  369.     static char *hapath=NULL;
  370.     
  371.     if (hapath!=NULL) free(hapath),hapath=NULL;
  372.     j=strlen(mdpath);
  373.     for (i=0;mdpath[i];++i) if (mdpath[i]!='.' && mdpath[i]!='/') break;
  374.     while (i>0 && mdpath[i-1]=='.') --i;
  375.     if (i==0) skipemptypath=1; 
  376.     else skipemptypath=0;
  377.     if ((hapath=malloc(j+1-i))==NULL) error(1,ERR_MEM,"md_tohapath()");
  378.     strcpy(hapath,mdpath+i);
  379.     for (i=0;hapath[i];++i) if (hapath[i]=='/') hapath[i]=0xff;
  380.     return md_strcase(hapath);
  381. }
  382.  
  383. char *md_tomdpath(char *hapath) {    
  384.     
  385.     int i;
  386.     static char *mdpath=NULL;
  387.     
  388.     if (mdpath!=NULL) free(mdpath),mdpath=NULL;
  389.     if ((mdpath=malloc(strlen(hapath)+1))==NULL) 
  390.       error(1,ERR_MEM,"md_tomdpath()");
  391.     strcpy(mdpath,hapath);
  392.     for (i=0;mdpath[i];++i) if ((unsigned char)mdpath[i]==0xff) mdpath[i]='/';
  393.     return mdpath;
  394. }
  395.  
  396. char *md_strippath(char *mdfullpath) {
  397.     
  398.     int i;
  399.     static char *plainpath=NULL;
  400.     
  401.     if (plainpath!=NULL) free(plainpath),plainpath=NULL;
  402.     if ((plainpath=malloc(strlen(mdfullpath)+1))==NULL) 
  403.       error(1,ERR_MEM,"md_strippath()");
  404.     strcpy(plainpath,mdfullpath);
  405.     for (i=strlen(plainpath)-1;i>=0;i--) {
  406.     if (plainpath[i]=='/') break; 
  407.     }
  408.     plainpath[i+1]=0;
  409.     return plainpath;
  410. }
  411.  
  412. char *md_stripname(char *mdfullpath) {
  413.     
  414.     int i;
  415.     static char *plainname=NULL;
  416.     
  417.     if (plainname!=NULL) free(plainname),plainname=NULL;
  418.     if ((plainname=malloc(strlen(mdfullpath)+1))==NULL) 
  419.       error(1,ERR_MEM,"md_stripname()");
  420.     for (i=strlen(mdfullpath)-1;i>0;i--) {
  421.     if (mdfullpath[i]=='/') {
  422.         i++;
  423.         break;
  424.     }
  425.     }
  426.     strcpy(plainname,mdfullpath+i);
  427.     return plainname;
  428. }
  429.  
  430. char *md_pconcat(int delim2, char *head, char *tail) {
  431.     
  432.     char *newpath;
  433.     int headlen,delim1;
  434.     
  435.     delim1=0;
  436.     if ((headlen=strlen(head))!=0)  {
  437.     if (head[headlen-1]!='/') delim1=1;
  438.     }
  439.     if ((newpath=malloc(headlen+strlen(tail)+delim2+delim1+1))==NULL) 
  440.       error(1,ERR_MEM,"md_pconcat()");
  441.     if (headlen!=0) strcpy(newpath,head);
  442.     if (delim1) newpath[headlen]='/';
  443.     strcpy(newpath+headlen+delim1,tail);
  444.     if (delim2) strcpy(newpath+strlen(newpath),"/");
  445.     return newpath;
  446. }
  447.  
  448. int md_namecmp(char *pat, char *cmp) {
  449.  
  450.     if (*pat==0) return !*cmp;
  451.     if (*pat=='?') {
  452.     if (!*cmp) return 0;
  453.     return md_namecmp(pat+1,cmp+1); 
  454.     }
  455.     if (*pat=='*') {
  456.     if (*(pat+1)==0) return 1;
  457.     for (;*cmp;++cmp) {
  458.         if (md_namecmp(pat+1,cmp)) return 1;
  459.     }
  460.     return 0;
  461.     }
  462.     if (*pat=='\\') {
  463.     ++pat;
  464.     if (*pat==0) return 0;
  465.     }
  466.     if (*pat==*cmp) return md_namecmp(pat+1,cmp+1);
  467.     return 0;
  468. }
  469.  
  470.  
  471.  
  472.